<?php

namespace App\Repository;

use App\Entity\Organization;
use App\Utils\Base\FilterBase;
use App\Utils\Enum\AdminModuleEnum;
use App\Utils\Filter\Admin\System\NoticeFilter;
use App\Utils\Filter\Admin\User\AdminUserFilter;
use App\Utils\Filter\Admin\User\OrganizationFilter;
use App\Utils\Traits\FilterTrait;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @method Organization|null find($id, $lockMode = null, $lockVersion = null)
 * @method Organization|null findOneBy(array $criteria, array $orderBy = null)
 * @method Organization[]    findAll()
 * @method Organization[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class OrganizationRepository extends ServiceEntityRepository {
    use FilterTrait;

    public function __construct (ManagerRegistry $registry) {
        parent::__construct($registry, Organization::class);
    }

    // /**
    //  * @return Organization[] Returns an array of Organization objects
    //  */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('o')
            ->andWhere('o.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('o.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */

    /*
    public function findOneBySomeField($value): ?Organization
    {
        return $this->createQueryBuilder('o')
            ->andWhere('o.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */

    /**
     * 获取字段和对应值并且不等于ID值的数据
     * @param $field
     * @param $value
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function findOneByFieldAndNotId ($field, $value, $id) {
        return $this->createQueryBuilder('a')
            ->where('a.id != :id')
            ->andWhere('a.'.$field.' = :field')
            ->setParameter('id', $id)
            ->setParameter('field', $value)
            ->getQuery()
            ->getOneOrNullResult();
    }

    /**
     * 查询
     * @param array $params
     * @return array
     */
    public function search ($params = []) {
        $result = [];
        $objs = $this->filter(new OrganizationFilter($params))
            ->select(FilterBase::ALIAS.'.id', FilterBase::ALIAS.'.parent_id', FilterBase::ALIAS.'.name', FilterBase::ALIAS.'.id as sort',)
            ->andWhere(FilterBase::ALIAS.'.status = 1')
            ->orderBy(FilterBase::ALIAS.'.id', 'ASC')
            ->getQuery()
            ->getArrayResult();

        // 整合成id为键的数组
        $items = [];
        foreach ($objs as $module) {
            $items[$module['id']] = $module;
        }

        // 通过引用实现无限分类
        foreach ($items as $key => $module) {
            if (isset($items[$module['parent_id']])) {
                $items[$module['parent_id']]['children'][] = &$items[$key];
            } else {
                $items[$key]['children'] = [];
                $result[$items[$key]['sort']] = &$items[$key];
            }
        }

        // children排序处理
        foreach ($result as &$module) {
            $sort_array = [];
            foreach ($module['children'] as $children) {
                $sort_array[$children['sort']] = $children;
            }
            ksort($sort_array);
            $module['children'] = array_merge($sort_array);
        }

        ksort($result);

        return array_merge($result);
    }

    /**
     * 获取组织架构子节点集合
     * @param int $id
     * @return array
     */
    public function getChildNodes (int $id) {
        $result = [];

        $objs = $this->createQueryBuilder('o')
            ->select('o.id', 'o.parent_id')
            ->andWhere('o.status = 1')
            ->andWhere('o.parent_id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->getArrayResult();

        foreach ($objs as $obj) {
            array_push($result, $obj['id']);
            $result = array_merge($result, $this->getChildNodes($obj['id']));
        }

        return $result;
    }

    /**
     * 批量删除组织架构
     * @param array $ids
     * @throws \Doctrine\DBAL\Driver\Exception
     * @throws \Doctrine\DBAL\Exception
     */
    public function batchRemove (array $ids = []) {
        if ($ids) {
            $conn = $this->getEntityManager()->getConnection();
            $date = new \DateTime();
            $sql = 'UPDATE organization SET status = 0, updated_at = \''.$date->format('Y-m-d H:i:s').'\' WHERE id in ('.implode(',', $ids).')';
            $stmt = $conn->prepare($sql);
            $stmt->execute();
        }
    }
}
